package com.zd.commodity.dao.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class SqlManager
{
  private static boolean debug = true;

  private static final Logger log = Logger.getLogger(SqlManager.class);

  private static final Map<Class, SqlTree> sqlFileMap = new HashMap();

  public static void loadSqlFile(Class cls)
  {
    String sqlFileName = "/SQL.xml";
    SAXReader saxReader = new SAXReader();
    saxReader.setEntityResolver(new EntityResolver()
    {
      public InputSource resolveEntity(String publicId, String systemId)
        throws SAXException, IOException
      {
        return new InputSource(SqlManager.class
          .getResourceAsStream("/sqls.dtd"));
      }
    });
    InputStream is = cls.getResourceAsStream(sqlFileName);
    SqlTree tree = new SqlTree();
    try
    {
      Document document = saxReader.read(is);
      Element root = document.getRootElement();
      for (Iterator i = root.elementIterator("query"); i.hasNext(); )
      {
        Element query = (Element)i.next();

        tree.addSql(query.attributeValue("id"), query.getText(), query
          .attributeValue("extend"), query
          .attributeValue("comment"), query
          .attributeValue("test"));
      }
      is.close();
    }
    catch (DocumentException e)
    {
      log.debug(e.getClass().getName() + ":" + e.getMessage());
    }
    catch (IOException e)
    {
      log.debug(e.getMessage());
    }

    sqlFileMap.put(cls, tree);
  }

  private static SqlTree getSqlTree(Class cls)
    throws Exception
  {
    SqlTree tree = (SqlTree)sqlFileMap.get(cls);
    if (debug)
    {
      loadSqlFile(cls);
      tree = (SqlTree)sqlFileMap.get(cls);
    }
    else if (tree == null)
    {
      loadSqlFile(cls);
      tree = (SqlTree)sqlFileMap.get(cls);
    }
    if (tree == null)
    {
      throw new Exception("类[" + cls + "]没有对应的sql文件");
    }
    return tree;
  }

  public static String getSqlText(Class cls, String id)
  {
    try
    {
      return getSqlTree(cls).getSqlText(id);
    }
    catch (Exception e)
    {
      log.error("Load SQL.XML ERROR", e);
    }return null;
  }

  private static class SqlTree
  {
    Map<String, SqlNode> SQLMap = new HashMap();

    void addSql(String id, String text, String extend, String comment, String test)
    {
      this.SQLMap.put(id, new SqlNode(id, text, extend, comment, test));
    }

    String getSqlText(String id)
    {
      try
      {
        SqlNode node = (SqlNode)this.SQLMap.get(id);
        if (node == null)
        {
          SqlManager.log.error("sql queryId = [" + id + "] 在SQL.xml中不存在！");
          return null;
        }

        return node.text;
      }
      catch (Exception e)
      {
      }
      return null;
    }

    class SqlNode
    {
      String text;

      public SqlNode(String id, String text, String extend, String comment, String test)
      {
        this.text = text;
      }
    }
  }
}
